package com.quectel.dms.controller.quectel;

import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.quectel.business.common.device.DeviceExtraAttrCls;
import com.quectel.business.dms.AccessorUtils;
import com.quectel.business.dms.application.ApplicationAccessConf;
import com.quectel.business.dms.application.access.accessor.ieg.AbstractIntelligentEntranceGuardAccessor;
import com.quectel.constant.core.entranceguard.EntranceGuardPersonConstants;
import com.quectel.core.module.application.dto.ApplicationDto;
import com.quectel.core.module.application.service.ApplicationService;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.entranceguard.dto.EntranceGuardPersonDto;
import com.quectel.core.module.entranceguard.dto.mongo.MongoPersonAccessRecordDto;
import com.quectel.core.module.entranceguard.service.EntranceGuardPersonService;
import com.quectel.core.module.household.dto.HouseholdDto;
import com.quectel.core.module.household.service.HouseholdService;
import com.quectel.dms.controller.BaseController;
import com.quectel.sdk.quecentrance.QuecEntranceClientBuilder;
import com.quectel.sdk.quecentrance.entranceguard.EntranceGuardClient;
import com.quectel.sdk.quecentrance.entranceguard.model.QueryUserReq;
import com.quectel.sdk.quecentrance.entranceguard.model.QueryUserResp;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.Response;
import com.quectel.util.redis.RedisUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 在这里编写说明
 *
 * @author: ryan
 * @email: ryan.ran@quectel.com
 * @date: 2023-08-21 14:46:00
 */

@RestController
@RequestMapping("quectelEntranceGuardCollect")
@Tag(name = "QuecEntranceGuardController")
@Slf4j
public class QuecEntranceGuardCollectController extends BaseController {

    private static final String REPEAT_MSG_KEY = "repeat_msg_key:";

    @DubboReference
    private DeviceService deviceService;
    @DubboReference
    private EntranceGuardPersonService entranceGuardPersonService;
    @DubboReference
    private HouseholdService householdService;
    @DubboReference
    private ApplicationService applicationService;

    @PostMapping("eventRcv/{callBackPath}")
    public Response<Object> eventRcv(@PathVariable String callBackPath, @RequestBody String msg) {
        log.debug("移远门禁事件 {} {}", callBackPath, msg);

        JsonNode msgJson = JacksonUtils.parse(msg);
        String messageId = msgJson.get("messageId").asText();

        Boolean setnx = RedisUtils.setnx(REPEAT_MSG_KEY + messageId, messageId, 1, TimeUnit.DAYS);
        if (setnx) {
            long timestamp = msgJson.get("timestamp").asLong();

            JsonNode dataJson = msgJson.get("data");
            String sn = dataJson.get("sn").asText();
            int personId = dataJson.get("id").asInt();
            String signAvatar = null;
            JsonNode signAvatarJson = dataJson.get("avatar");
            if (signAvatarJson != null) {
                signAvatar = signAvatarJson.asText();
            }

            List<DeviceDto> deviceDtos =
                    deviceService.selectCacheByUniqueId(sn);
            if (CollectionUtils.isNotEmpty(deviceDtos)) {
                for (DeviceDto deviceDto : deviceDtos) {

                    MongoPersonAccessRecordDto personAccessRecordDto = new MongoPersonAccessRecordDto();
                    personAccessRecordDto.setTenantId(deviceDto.getTenantId());
                    personAccessRecordDto.setVillageId(deviceDto.getVillageId());
                    personAccessRecordDto.setBuildingId(deviceDto.getBuildingId());
                    personAccessRecordDto.setDeviceCategoryId(deviceDto.getDeviceCategoryId());
                    personAccessRecordDto.setDeviceTypeId(deviceDto.getDeviceTypeId());
                    personAccessRecordDto.setDeviceId(deviceDto.getId());
                    personAccessRecordDto.setDeviceName(deviceDto.getName());


                    //优先查询数据库是否已经绑定关系
                    EntranceGuardPersonDto bindPerson = entranceGuardPersonService.queryAuthBy(deviceDto.getId(), String.valueOf(personId));
                    if (bindPerson != null) {
                        if (EntranceGuardPersonConstants.PersonTypeEnum.HOUSEHOLD.getType().equals(bindPerson.getPersonType())) {
                            HouseholdDto householdDto = householdService.selectById(bindPerson.getPersonId());
                            if (householdDto != null) {
                                personAccessRecordDto.setPersonType(EntranceGuardPersonConstants.PersonTypeEnum.HOUSEHOLD.getType());
                                personAccessRecordDto.setPersonId(householdDto.getId());
                                personAccessRecordDto.setPersonName(householdDto.getName());
                                personAccessRecordDto.setPersonMobile(householdDto.getMobile());

                            }
                        }
                    } else {

                        ApplicationDto application = applicationService.selectCacheById(deviceDto.getApplicationId());

                        ApplicationAccessConf.TemplateOfQuecAttendanceConf templateOfQuecAttendanceConf = ApplicationAccessConf
                                .parseExtStr(ApplicationAccessConf.TemplateOfQuecAttendanceConf.class, application.getAccessConf());

                        assert templateOfQuecAttendanceConf != null;
                        EntranceGuardClient build = QuecEntranceClientBuilder.builder()
                                .appKey(templateOfQuecAttendanceConf.getAppKey()).appSecret(templateOfQuecAttendanceConf.getAppSecret()).baseUrl(templateOfQuecAttendanceConf.getBaseUrl())
                                .build(com.quectel.sdk.quecentrance.entranceguard.EntranceGuardClient.class);

                        QueryUserReq queryUserReq = new QueryUserReq();
                        queryUserReq.setId((long) personId);
                        List<QueryUserResp> queryUserResps = build.queryUserList(queryUserReq);
                        if (CollectionUtils.isNotEmpty(queryUserResps)) {
                            QueryUserResp queryUserResp = queryUserResps.get(0);

                            personAccessRecordDto.setPersonType(EntranceGuardPersonConstants.PersonTypeEnum.HOUSEHOLD.getType());

                            HouseholdDto householdDto = householdService.selectCacheByVillageIdAndMobile(deviceDto.getVillageId(), queryUserResp.getMobile());
                            if (householdDto == null) {
                                personAccessRecordDto.setPersonId(null);
                                personAccessRecordDto.setPersonName(queryUserResp.getName());
                                personAccessRecordDto.setPersonMobile(queryUserResp.getMobile());
                            } else {
                                personAccessRecordDto.setPersonId(householdDto.getId());
                                personAccessRecordDto.setPersonName(householdDto.getName());
                                personAccessRecordDto.setPersonMobile(householdDto.getName());

                                EntranceGuardPersonDto saveObj = new EntranceGuardPersonDto();

                                EntranceGuardPersonDto entranceGuardPersonDto = entranceGuardPersonService.queryAuthBy(deviceDto.getId()
                                        , EntranceGuardPersonConstants.PersonTypeEnum.HOUSEHOLD.getType(), householdDto.getId());
                                if (entranceGuardPersonDto == null) {
                                    saveObj.setTenantId(deviceDto.getTenantId());
                                    saveObj.setAuthType(EntranceGuardPersonConstants.AuthTypeEnum.ADD.getAuthType());
                                    saveObj.setDeviceId(deviceDto.getId());
                                    saveObj.setPersonType(EntranceGuardPersonConstants.PersonTypeEnum.HOUSEHOLD.getType());
                                    saveObj.setPersonId(householdDto.getId());
                                    saveObj.setIdentityAtDevice(String.valueOf(personId));
                                    saveObj.setAuthStatus(EntranceGuardPersonConstants.AuthStatusEnum.SEND_SUCCESS.getAuthStatus());
                                    saveObj.setStartTime(new Date());
                                    saveObj.setEndTime(DateUtil.offsetDay(new Date(), 365 * 10));
                                    saveObj.setCreateTime(new Date());
                                    entranceGuardPersonService.save(saveObj);
                                } else {
                                    EntranceGuardPersonDto updateObj = new EntranceGuardPersonDto();
                                    updateObj.setId(entranceGuardPersonDto.getId());
                                    updateObj.setIdentityAtDevice(String.valueOf(personId));
                                    entranceGuardPersonService.updateById(updateObj);
                                }


                            }

                        }
                    }

                    personAccessRecordDto.setAccessMode((byte) 4);

                    DeviceExtraAttrCls.AttrOfIntelligentEntranceGuard attrOfIntelligentEntranceGuard = DeviceExtraAttrCls.parseExtStr(DeviceExtraAttrCls.AttrOfIntelligentEntranceGuard.class
                            , deviceDto.getExtraAttr());

                    if (attrOfIntelligentEntranceGuard != null) {
                        personAccessRecordDto.setOutOrIn(attrOfIntelligentEntranceGuard.getOutOrIn());
                    }

                    if (StringUtils.isNotBlank(signAvatar)) {
                        personAccessRecordDto.setSnapImages(JacksonUtils.toJsonString(Collections.singletonList(signAvatar)));
                    }
                    personAccessRecordDto.setEventTime(new Date(timestamp));
                    personAccessRecordDto.setLongitude(deviceDto.getLongitude());
                    personAccessRecordDto.setLatitude(deviceDto.getLatitude());

                    AbstractIntelligentEntranceGuardAccessor intelligentEntranceGuardAccessor = AccessorUtils.getIntelligentEntranceGuardAccessor(deviceDto.getDeviceType());
                    assert intelligentEntranceGuardAccessor != null;
                    intelligentEntranceGuardAccessor.accessRecordHand(personAccessRecordDto);
                }
            }
        }
        return Response.ok();
    }
}
